<template>
  <!-- 
    组件配置对话框组件
    功能：
    1. 动态生成配置表单
    2. 支持多种数据类型（字符串、数字、布尔值、数组、对象等）
    3. JSON配置编辑器
    4. 表单验证
    5. 配置预览
  -->
  <div class="widget-config">
    <el-form
      ref="configFormRef"
      :model="configForm"
      :rules="configRules"
      label-width="120px"
      label-position="left"
    >
      <div v-if="configFields.length > 0">
        <div v-for="field in configFields" :key="field.name">
          <!-- 文本输入 -->
          <el-form-item 
            v-if="field.type === 'string' && !field.enum"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-input
              v-model="configForm[field.name]"
              :placeholder="field.description || `请输入${field.title || field.name}`"
              :disabled="loading"
            />
          </el-form-item>

          <!-- 数字输入 -->
          <el-form-item 
            v-else-if="field.type === 'number' || field.type === 'integer'"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-input-number
              v-model="configForm[field.name]"
              :min="field.minimum"
              :max="field.maximum"
              :step="field.type === 'integer' ? 1 : 0.1"
              :placeholder="field.description || `请输入${field.title || field.name}`"
              :disabled="loading"
              style="width: 100%"
            />
          </el-form-item>

          <!-- 布尔值 -->
          <el-form-item 
            v-else-if="field.type === 'boolean'"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-switch
              v-model="configForm[field.name]"
              :disabled="loading"
              :active-text="field.description || '启用'"
            />
          </el-form-item>

          <!-- 选择器 -->
          <el-form-item 
            v-else-if="field.enum"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-select
              v-model="configForm[field.name]"
              :placeholder="field.description || `请选择${field.title || field.name}`"
              :disabled="loading"
              style="width: 100%"
            >
              <el-option
                v-for="option in field.enum"
                :key="option"
                :label="option"
                :value="option"
              />
            </el-select>
          </el-form-item>

          <!-- 数组 -->
          <el-form-item 
            v-else-if="field.type === 'array'"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-select
              v-model="configForm[field.name]"
              multiple
              :placeholder="field.description || `请选择${field.title || field.name}`"
              :disabled="loading"
              style="width: 100%"
            >
              <el-option
                v-for="option in getArrayOptions(field)"
                :key="option"
                :label="option"
                :value="option"
              />
            </el-select>
          </el-form-item>

          <!-- 对象 -->
          <el-form-item 
            v-else-if="field.type === 'object'"
            :label="field.title || field.name"
            :prop="field.name"
          >
            <div class="object-config">
              <el-button 
                size="small" 
                @click="editObjectField(field)"
                :disabled="loading"
              >
                <el-icon><Edit /></el-icon>
                配置
              </el-button>
              <span class="object-preview">
                {{ getObjectPreview(configForm[field.name]) }}
              </span>
            </div>
          </el-form-item>

          <!-- 默认处理 -->
          <el-form-item 
            v-else
            :label="field.title || field.name"
            :prop="field.name"
          >
            <el-input
              v-model="configForm[field.name]"
              :placeholder="field.description || `请输入${field.title || field.name}`"
              :disabled="loading"
            />
          </el-form-item>
        </div>
      </div>

      <div v-else class="no-config">
        <el-empty description="该组件暂无可配置项" />
      </div>
    </el-form>

    <!-- 对象编辑器对话框 -->
    <el-dialog
      v-model="showObjectEditor"
      :title="`配置 ${currentObjectField?.title || currentObjectField?.name}`"
      width="600px"
    >
      <div class="object-editor">
        <el-input
          v-model="objectEditorContent"
          type="textarea"
          :rows="10"
          placeholder="请输入JSON格式的配置"
        />
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showObjectEditor = false">取消</el-button>
          <el-button type="primary" @click="saveObjectField">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 操作按钮 -->
    <div class="config-actions">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSave" :loading="loading">
        保存配置
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * 组件配置对话框组件
 * 
 * 功能：
 * 1. 动态生成配置表单，支持多种数据类型
 * 2. 基于JSON Schema生成表单字段
 * 3. 提供JSON编辑器用于复杂配置
 * 4. 表单验证和错误处理
 * 5. 配置预览和格式化
 * 
 * @component WidgetConfig
 */

import { ref, computed, onMounted, watch } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { useWidgetStore } from '@/stores/widget'
import type { UserWidget } from '@/stores/widget'

// ==================== 组件接口定义 ====================
/**
 * 组件属性接口
 * @interface Props
 */
interface Props {
  /** 用户组件实例 */
  widget: UserWidget
}

/**
 * 配置字段接口
 * @interface ConfigField
 */
interface ConfigField {
  /** 字段名称 */
  name: string
  /** 字段标题 */
  title?: string
  /** 字段描述 */
  description?: string
  /** 字段类型 */
  type: string
  /** 默认值 */
  default?: any
  /** 最小值（数字类型） */
  minimum?: number
  /** 最大值（数字类型） */
  maximum?: number
  /** 枚举值 */
  enum?: any[]
  /** 数组项配置 */
  items?: any
  /** 对象属性配置 */
  properties?: Record<string, any>
}

// ==================== 组件属性和事件 ====================
const props = defineProps<Props>()
const emit = defineEmits<{
  save: [config: any]
  cancel: []
}>()

// ==================== 依赖注入 ====================
const widgetStore = useWidgetStore()

// ==================== 表单状态管理 ====================
/** 表单引用 */
const configFormRef = ref<FormInstance>()
/** 表单数据 */
const configForm = ref<Record<string, any>>({})
/** 表单验证规则 */
const configRules = ref<FormRules>({})
/** 加载状态 */
const loading = ref(false)

// ==================== 对象编辑器状态 ====================
/** 是否显示对象编辑器 */
const showObjectEditor = ref(false)
/** 当前编辑的对象字段 */
const currentObjectField = ref<ConfigField | null>(null)
/** 对象编辑器内容 */
const objectEditorContent = ref('')

// ==================== 计算属性 ====================
/**
 * 配置字段列表
 * 根据组件的配置架构解析生成的可配置字段
 */
const configFields = computed<ConfigField[]>(() => {
  const widget = props.widget.widget
  if (!widget?.config_schema) return []

  try {
    const schema = JSON.parse(widget.config_schema)
    return parseConfigSchema(schema)
  } catch {
    return []
  }
})

// ==================== 配置架构解析函数 ====================
/**
 * 解析配置架构生成配置字段
 * @param schema - JSON Schema配置架构
 * @param prefix - 字段名称前缀（用于嵌套对象）
 * @returns 配置字段列表
 */
function parseConfigSchema(schema: any, prefix = ''): ConfigField[] {
  const fields: ConfigField[] = []

  if (schema.type === 'object' && schema.properties) {
    for (const [key, value] of Object.entries(schema.properties)) {
      const field: ConfigField = {
        name: prefix ? `${prefix}.${key}` : key,
        title: (value as any).title,
        description: (value as any).description,
        type: (value as any).type,
        default: (value as any).default,
        minimum: (value as any).minimum,
        maximum: (value as any).maximum,
        enum: (value as any).enum,
        items: (value as any).items,
        properties: (value as any).properties
      }
      fields.push(field)
    }
  }

  return fields
}

// ==================== 数组和对象处理函数 ====================
/**
 * 获取数组字段的选项列表
 * @param field - 配置字段
 * @returns 选项数组
 */
function getArrayOptions(field: ConfigField): any[] {
  if (field.items?.enum) {
    return field.items.enum
  }
  
  // 提供一些默认选项
  if (field.name?.includes('priority')) {
    return ['low', 'medium', 'high']
  }
  
  if (field.name?.includes('status')) {
    return ['active', 'inactive', 'pending']
  }
  
  if (field.name?.includes('size')) {
    return ['small', 'medium', 'large']
  }
  
  return []
}

/**
 * 获取对象字段的预览文本
 * @param value - 对象值
 * @returns 预览文本
 */
function getObjectPreview(value: any): string {
  if (!value) return '未配置'
  
  if (typeof value === 'string') {
    try {
      const parsed = JSON.parse(value)
      return JSON.stringify(parsed, null, 2).substring(0, 100) + '...'
    } catch {
      return value.substring(0, 100) + '...'
    }
  }
  
  return JSON.stringify(value, null, 2).substring(0, 100) + '...'
}

// ==================== 对象编辑器函数 ====================
/**
 * 打开对象字段编辑器
 * @param field - 要编辑的对象字段
 */
function editObjectField(field: ConfigField) {
  currentObjectField.value = field
  const currentValue = configForm.value[field.name]
  
  if (typeof currentValue === 'string') {
    objectEditorContent.value = currentValue
  } else {
    objectEditorContent.value = JSON.stringify(currentValue, null, 2)
  }
  
  showObjectEditor.value = true
}

/**
 * 保存对象字段配置
 * 验证JSON格式并保存到表单数据中
 */
function saveObjectField() {
  if (!currentObjectField.value) return
  
  try {
    const parsed = JSON.parse(objectEditorContent.value)
    configForm.value[currentObjectField.value.name] = parsed
    showObjectEditor.value = false
    ElMessage.success('配置已保存')
  } catch {
    ElMessage.error('JSON格式错误，请检查输入')
  }
}

// ==================== 表单初始化和验证函数 ====================
/**
 * 生成表单验证规则
 * 根据字段类型生成相应的验证规则
 */
function generateFormRules() {
  const rules: FormRules = {}
  
  configFields.value.forEach(field => {
    if (field.type === 'string' && !field.enum) {
      rules[field.name] = [
        { required: false, message: `请输入${field.title || field.name}`, trigger: 'blur' }
      ]
    } else if (field.type === 'number' || field.type === 'integer') {
      rules[field.name] = [
        { required: false, message: `请输入${field.title || field.name}`, trigger: 'blur' },
        { type: 'number', message: '请输入有效的数字', trigger: 'blur' }
      ]
    }
  })
  
  configRules.value = rules
}

/**
 * 初始化配置表单
 * 根据当前配置和默认值初始化表单数据
 */
function initConfigForm() {
  const currentConfig = widgetStore.parseWidgetConfig(props.widget.config_data)
  const form: Record<string, any> = {}
  
  configFields.value.forEach(field => {
    // 优先使用当前配置，其次使用默认值
    form[field.name] = currentConfig[field.name] ?? field.default ?? getDefaultValue(field.type)
  })
  
  configForm.value = form
  generateFormRules()
}

/**
 * 根据字段类型获取默认值
 * @param type - 字段类型
 * @returns 默认值
 */
function getDefaultValue(type: string): any {
  switch (type) {
    case 'string':
      return ''
    case 'number':
    case 'integer':
      return 0
    case 'boolean':
      return false
    case 'array':
      return []
    case 'object':
      return {}
    default:
      return null
  }
}

// ==================== 事件处理函数 ====================
/**
 * 处理保存操作
 * 验证表单并发送保存事件
 */
async function handleSave() {
  if (!configFormRef.value) return
  
  try {
    await configFormRef.value.validate()
    loading.value = true
    
    // 发送保存事件
    emit('save', configForm.value)
  } catch (error) {
    ElMessage.error('请检查配置项')
  } finally {
    loading.value = false
  }
}

/**
 * 处理取消操作
 * 发送取消事件
 */
function handleCancel() {
  emit('cancel')
}

// ==================== 生命周期钩子 ====================
/**
 * 监听配置字段变化，重新初始化表单
 */
watch(configFields, () => {
  initConfigForm()
}, { immediate: true })

/**
 * 组件挂载时初始化表单
 */
onMounted(() => {
  initConfigForm()
})
</script>

<style scoped>
.widget-config {
  padding: 20px 0;
}

.no-config {
  padding: 40px 0;
  text-align: center;
}

.object-config {
  display: flex;
  align-items: center;
  gap: 12px;
}

.object-preview {
  flex: 1;
  font-size: 12px;
  color: var(--text-color-secondary);
  background: var(--bg-color-secondary);
  padding: 8px 12px;
  border-radius: var(--radius-md);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.object-editor {
  margin-bottom: 20px;
}

.config-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border-color);
}

@media (max-width: 768px) {
  .widget-config {
    padding: 16px 0;
  }
  
  .object-config {
    flex-direction: column;
    align-items: stretch;
  }
  
  .config-actions {
    flex-direction: column;
  }
  
  .config-actions .el-button {
    width: 100%;
  }
}
</style>